package weilus.clients;

import weilus.StreamChannel;
import weilus.clients.dtos.MQMessage;
import com.weilus.refresh.ConsumerConfigMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Map;

@Configuration
@Slf4j
public class FluxService {

    @Autowired
    ConsumerConfigMap config;
    @Autowired
    private StreamChannel source;
    @Autowired
    ReactorLoadBalancerExchangeFilterFunction lbFunction;
    @Autowired
    ReactiveCircuitBreakerFactory cbFactory;

    public Mono<String> sayHello(Map map){
        return WebClient.builder()
                .filter(lbFunction)
                .build()
                .post()
                .uri(config.getSayHello())
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(map)
                .retrieve()
                .bodyToMono(String.class);
    }

    public Mono<String> hiMan(Map<String, String> map){
        return WebClient.builder()
                .filter(lbFunction)
                .build()
                .post()
                .uri(config.getHiMan())
                .bodyValue(map)
                .retrieve()
                .bodyToMono(String.class);
    }

    public Mono<Void> hiMan1(Map<String, String> map){
         return WebClient.builder()
                 .filter(lbFunction)
                 .build()
                 .post()
                 .uri(config.getHiMan())
                 .bodyValue(map)
                 .retrieve()
                 .bodyToMono(Void.class);
    }

    /**
     * 写登录日志
     */
    public Mono<String> loginLog(MQMessage msg){
        msg.setRoutingKey("loginLog");
        return WebClient.builder()
                .filter(lbFunction)
                .build()
                .post()
                .uri(config.getLoginLog())
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(msg)
                .retrieve()
                .bodyToMono(String.class)
                .transform(it->fallback(it,msg));
    }

    /**
     * 每日签到红包
     */
    public Mono<String> everyDayMoney(MQMessage msg){
        msg.setRoutingKey("everyDayMoney");
        return WebClient.builder()
                .filter(lbFunction)
                .build()
                .post()
                .uri(config.getEveryDayMoney())
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(msg)
                .retrieve()
                .bodyToMono(String.class)
                .transform(it->fallback(it,msg));
    }

    public Mono fallback(Mono it,MQMessage msg){
        return cbFactory.create(msg.getRoutingKey()).run(it,ex->{
            msg.setType(ex);
            this.source.output().send(MessageBuilder.withPayload(msg).build());
            return Mono.just("fallback");
        });
    }

}
